#ifndef _UC_SEGMENT_FLASH_MANAGER_H_
#define _UC_SEGMENT_FLASH_MANAGER_H_


typedef enum
{
    SEGMENT_PARSING_SUCCESS = 0,
    SEGMENT_PARSING_APPEND_FAIL,
    SEGMENT_PARSING_MERGE_FAIL,
    SEGMENT_PARSING_OTHER_FAIL,
} e_segment_parsing_result;

typedef unsigned int (*flash_malloc)(int size);
typedef void (*flash_free)(unsigned int addr);
typedef int (*flash_read)(unsigned int addr, char *data, int len);
typedef int (*flash_write)(unsigned int addr, char *data, int len);

typedef struct
{
    flash_malloc malloc_func;
    flash_free free_func;
    flash_read read_func;
    flash_write write_func;
    int segment_data_len;
} t_flash_function;


typedef struct
{
    rt_list_t node;
    unsigned int src_addr;
    unsigned int create_packet_tick;
    unsigned char packet_num;
    unsigned char is_end;
    unsigned short total_num;
    unsigned char *segment_mask;
    unsigned int flash_addr;
    unsigned int flash_offset;
    void *parament;
} t_flash_data_packet;

/**
 * @brief package management initialization
 *
 */
void flash_segment_packet_init(flash_malloc malloc_func,
        flash_free free_func,
        flash_read read_func,
        flash_write write_func,
        int segment_data_len);


/**
 * @brief package management de initialization
 *
 */
void flash_segment_packet_deinit(void);


/**
 * @brief
 *
 * @return 0:no segment, 1: continue differentical packets,
        2: end differentical packets; 3: fail.
 *
 */
e_segment_parsing_result flash_packege_segment_parsing(void *header,
    void *in_data,
    unsigned int in_data_len,
    unsigned int *out_data_addr,
    unsigned int *out_data_len,
    void *user_parament,
    void *(*segment_callback)(void* segment_manager, void *user_parament),
    void **get_manager_page);

/**
 * @brief
 *
 * @return 0:success
 *
 */

int flash_get_loss_block(unsigned int src_addr,
    unsigned char packet_num,
    unsigned char **mask,
    int *pos,
    int *mask_len,
    int * loss_num);

/**
 * @brief
 *
 * @return 0:fail, other: success
 *
 */
unsigned int flash_get_packet_tick(unsigned int addr, unsigned char packet_num);

/**
 * @brief
 *
 * @return
 *
 */
unsigned int flash_get_segment_manager(unsigned int addr, unsigned char packet_num);


/**
 * @brief  call this interface to release memory after data recved and merged
 *
 * @param  data_packet: recved data packet
 *
 */
void flash_seg_packet_clear(unsigned int addr, unsigned char packet_num);

#endif
